/*
 * Copyright 2013-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.denghq.projectbuilder.component.nacos.config.client;


import com.denghq.projectbuilder.common.util.BeanTool;
import com.denghq.projectbuilder.component.config.metadata.ConfigDescriptor;
import com.denghq.projectbuilder.component.config.spring.ConfigPropertySource;
import com.denghq.projectbuilder.component.nacos.config.NacosConfigAutoRegister;
import com.denghq.projectbuilder.component.nacos.config.NacosConfigProperties;
import com.denghq.projectbuilder.component.nacos.config.NacosPropertySourceRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * @author xiaojing
 * @author pbting
 */
@Order(0)
public class NacosPropertySourceLocator implements PropertySourceLocator {

    private static final Logger log = LoggerFactory
            .getLogger(NacosPropertySourceLocator.class);

    private static final String NACOS_PROPERTY_SOURCE_NAME = "NACOS";

    private static final String SEP1 = "-";

    private static final String DOT = ".";

    private NacosPropertySourceBuilder nacosPropertySourceBuilder;


    private final List<ConfigDescriptor> configDescriptorList;
    private final NacosConfigAutoRegister configAutoRegister;
    private final NacosConfigProperties properties;


    public NacosPropertySourceLocator(List<ConfigDescriptor> configDescriptorList, NacosConfigAutoRegister configAutoRegister, NacosConfigProperties properties) {
        this.configDescriptorList = configDescriptorList;
        this.configAutoRegister = configAutoRegister;
        this.properties = properties;
    }

    @Override
    public PropertySource<?> locate(Environment env) {
        List<ConfigDescriptor> configsFromRemote = configAutoRegister.getConfigsFromRemote(configDescriptorList);
        if (!(env instanceof ConfigurableEnvironment)) {
            return null;
        } else {
            CompositePropertySource composite = new CompositePropertySource(NACOS_PROPERTY_SOURCE_NAME);
            if (!CollectionUtils.isEmpty(configsFromRemote)) {
                configsFromRemote.forEach(e -> {
                    ConfigPropertySource propertySource;
                    propertySource = this.create(e);
                    if (propertySource != null) {
                        composite.addPropertySource((propertySource));
                        NacosPropertySourceRepository.collectNacosPropertySource(new NacosPropertySource(properties.getGroup(), e.getCategoryNo(), propertySource.getProperties(), new Date(), properties.isRefreshEnabled()));
                    }
                });
            }
            return composite;
        }


    }

    private ConfigPropertySource create(ConfigDescriptor value) {
        ConfigPropertySource propertySource = null;
        if (!CollectionUtils.isEmpty(configDescriptorList)) {
            for (int i = 0, len = configDescriptorList.size(); i < len; i++) {
                if (value.getCategoryNo().equals(configDescriptorList.get(i).getCategoryNo())) {
                    propertySource = new ConfigPropertySource(value.getCategoryNo(), BeanTool.objectToJsonStr(value), configDescriptorList.get(i));
                    propertySource.init();
                    break;
                }
            }
        }
        return propertySource;
    }

}
